﻿using BusinessManage.Common;
using CPFrameWork.Global;
using CPFrameWork.Utility;
using CPFrameWork.Utility.DbOper;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NLog;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;

namespace BusinessManage.TaskAutoCreate
{
    public class TaskAutoCreateController : CPWebApiBaseController
    {

        DbHelper _helper = new DbHelper("CPYKWL", CPAppContext.CurDbType());
        DbHelper _dephelper = new DbHelper("CPOrganIns", CPAppContext.CurDbType());
        private readonly Logger log = LogManager.GetCurrentClassLogger();
        
        /// <summary>
        /// 功能：根据选择预计发货日期进行自动排线
        /// </summary>
        /// <param name="TaskDate">预计发货日期</param>
        /// <returns></returns>
        [HttpGet]
        public string CreateTask(string TaskDate)
        {
            string UserId = CPAppContext.GetHttpContext().Session.GetString("UserId");
            string BaseId = CPAppContext.GetHttpContext().Session.GetString("BaseId");
            log.Info("开始执行自动创建任务功能");
            DateTime Curdate = Convert.ToDateTime(TaskDate);
            string ServiceUrl = CPUtils.Configuration.GetSection("AppSettings")["CreateTaskService"];
            string strdepsql = "select * from CP_Dep where depid='"+ BaseId + "'";//获取当前登录人的基地信息
            log.Info("开始获取基地数据");
            DataTable dt = _dephelper.ExecuteDataSet(strdepsql).Tables[0];
            log.Info("获取基地数据结束");
            if (dt.Rows.Count > 0)
            {
                foreach (DataRow dr in dt.Rows)
                {
                    log.Info(string.Format("开始获取基地：{0}   的订单数据 ", dr["DepName"].ToString()));
                    JArray order = GetOrderInfo(dr, Curdate);
                    if (order.Count() == 0)
                    {
                        log.Info(string.Format("未获取基地：{0}   的日期为{1}的订单数据 ", dr["DepName"].ToString(), Curdate.ToString("yyy-MM-dd")));
                        return string.Format("未获取基地：{0}的日期为{1}的订单数据 ", dr["DepName"].ToString(), Curdate.ToString("yyy-MM-dd"));
                    }
                    log.Info(string.Format("开始获取基地：{0}   的车辆数据 ", dr["DepName"].ToString()));
                    JArray Carinfo = GetCarsInfo(dr);
                    JObject center = new JObject();
                    center.Add("name", dr["DepName"].ToString());
                    center.Add("longitude", Convert.ToDouble(dr["longitude"].ToString()));
                    center.Add("latitude", Convert.ToDouble(dr["latitude"].ToString()));
                    center.Add("address", dr["DepAddress"].ToString());
                    var param = new
                    {
                        servicetype = "1",
                        version = "1",
                        timestamp = "0",
                        ticket = "0",
                        sign = "0",
                        orders = order,
                        trucks = Carinfo,
                        center = center
                    };
                    log.Info(string.Format("开始获取向服务发送请求：{0} ，请求参数为：{1}", dr["DepName"].ToString(), JsonConvert.SerializeObject(param)));

                    //string data = RequestUtility.wphttppost.datapost(sParaTemp);
                    //4、获取接口中返回的数据
                    string result = "";
                    result = wphttppost.RestSharpPostRaw(ServiceUrl, JsonConvert.SerializeObject(param));
                    log.Info(string.Format("获取分组信息成功，基地名为：{0} 下一步数据解析入库\n{1}", dr["DepName"].ToString(), result));
                    try
                    {
                        //5、解析数据，插入原始表，添加同步时间
                        JObject joAccountResult = (JObject)JsonConvert.DeserializeObject(result);
                        //如何返回失败则记录日志
                        if (joAccountResult.Value<int>("status") == 200)
                        {
                            SaveDataInfo(joAccountResult, Curdate, UserId);
                            log.Info(string.Format("数据解析入库完成。自动分组完成！！！", dr["DepName"].ToString()));

                        }
                        //
                        else
                        {
                            log.Error(string.Format("解析数据时出错，数据返回状态错误。数据为{0}", joAccountResult.ToString()));
                            //请求失败 记录日志
                            return joAccountResult.Value<string>("des");
                        }
                    }
                    catch (Exception ex)
                    {
                        //-------从接口获取数据失败，写入日志
                        log.Error(string.Format("数据解析入库失败，失败信息为：{0}\n  详细信息为{1}   \n 服务返回数据为{2}", ex.Message, ex.StackTrace, result));
                        return "数据解析入库失败 ：" + ex.Message;
                    }
                }
            }
            else {
                return "未获取当前登录人的基地信息!";
            }
            return "排线完成";
        }
        /// <summary>
        /// 根据基地信息获取待分组订单信息
        /// </summary>
        /// <param name="baseinfo"></param>
        /// <returns></returns>
        private JArray GetOrderInfo(DataRow baseinfo, DateTime date)
        {
            string strdate = date.ToString("yyyy-MM-dd");
            string strOrderbase = "select distinct OrderCode orderid ," +
                " (select  sum(convert(int, BuyChickCount) + convert(int, AdjustNumber)+convert(int, LossCount)) from YW_OrderDetail where OrderId = w.OrderCode ) as uunitnum," +
                " 0 as weight,0 as volume,0 as longitude ,0 as latitude,'' as goodsInfo, " +
                " w.CustomerState + w.CustomerCity + w.CustomerDistrict + w.CustomerAddress as address " +
                " from dbo.YW_OrderInfo w left " +
                " join YW_GivetohallInfo g  on w.OrderCode = g.OrderId " +
                " left join YW_TaskOrderRelation r on r.OrderId = w.OrderCode " +
                " where r.TaskId is null and g.BaseId = '" + baseinfo["DepId"] + "' and WaitDeliveryTime between '" + strdate + " 00:00:00' and '" + strdate + " 23:59:59'";
            DataTable dtorderBase = _helper.ExecuteDataSet(strOrderbase).Tables[0];
            var Jarray = (JArray)JsonConvert.DeserializeObject(JsonConvert.SerializeObject(dtorderBase));
            foreach (JObject jo in Jarray)
            {
                string sql = "select Id givetohallid, BaseId baseid,BaseName basename,HallId hallid,HallName hallname,VarietyId verietyid,VarietyName varietyname,GoodsId goodsid,GoodsName goodsname,BuyChickCount buychickcount,HallLossCount halllosscount from  YW_GivetohallInfo where OrderId='" + jo["orderid"] + "'";
                DataTable dtordetail = _helper.ExecuteDataSet(sql).Tables[0];
                jo["goodsinfo"] = (JArray)JsonConvert.DeserializeObject(JsonConvert.SerializeObject(dtordetail));
            }
            return Jarray;
        }
        /// <summary>
        /// 根据基地信息获取车辆数据
        /// </summary>
        /// <param name="baseinfo"></param>
        /// <returns></returns>
        private JArray GetCarsInfo(DataRow baseinfo)
        {
            string SQL = "select * from ( select a.CarNumber,a.CarType,isnull(c.Value,0)Value from BD_CarInfo a left join BD_CarBorrowInfo b on a.Id = b.CarId and GETDATE()between b.StratTime and b.EndTime left join BD_TransportCapacity c on a.CarType = c.CarType and Month(GETDATE())= c.Month   and a.BaseId = c.DepId where b.BorrowBaseId is null and Replace(a.CarNumber,' ','') not in (select Replace(CarNumber, ' ', '')  from YW_TaskCarRelation where isnull(CarDeliveryStatus, 0) <> 3  )and a.BaseId = '" + baseinfo["DepId"] + "'   union select CarNumber,a.CarType,ISNULL(b.Value,0)Value from BD_CarInfo a  left join BD_TransportCapacity b on a.CarType = b.CarType and Month(GETDATE())= b.Month  and a.BaseId = b.DepId  where a.ID in (select carid from BD_CarBorrowInfo where BorrowBaseId = '" + baseinfo["DepId"] + "' and GETDATE() between StratTime and EndTime )) aa order by CarType";
            DataTable dtCar = _helper.ExecuteDataSet(SQL).Tables[0];
            if (dtCar.Rows.Count == 0)
            {
                return null;
            }
            DataRow oldrow = dtCar.NewRow();
            JArray carTyps = new JArray();
            JArray carArray = new JArray();
            for (int i = 0; i < dtCar.Rows.Count; i++)
            {
                if (i == 0)
                {
                    oldrow = dtCar.Rows[i];
                    carArray.Add(dtCar.Rows[i]["CarNumber"]);
                    continue;
                }
                if (dtCar.Rows[i]["CarType"].ToString().Equals(oldrow["CarType"].ToString()))
                {
                    carArray.Add(dtCar.Rows[i]["CarNumber"]);
                }
                else
                {
                    JObject jo1 = new JObject();
                    jo1.Add("truckclassid", oldrow["CarType"].ToString());
                    jo1.Add("truckunitnum", Convert.ToDouble(oldrow["Value"].ToString()));
                    jo1.Add("truckweight", 0);
                    jo1.Add("truckvolume", 0);
                    jo1.Add("truckidarray", carArray);
                    carTyps.Add(jo1.DeepClone());
                    carArray.Clear();
                    oldrow = dtCar.Rows[i];
                    carArray.Add(dtCar.Rows[i]["CarNumber"]);
                }
            }

            //添加最后一次车辆类型
            JObject jo = new JObject();
            jo.Add("truckclassid", oldrow["CarType"].ToString());
            jo.Add("truckunitnum", Convert.ToDouble(oldrow["Value"].ToString()));
            jo.Add("truckweight", 0);
            jo.Add("truckvolume", 0);
            jo.Add("truckidarray", carArray);
            carTyps.Add(jo.DeepClone());

            return carTyps;
        }


        /// <summary>
        /// 解析自动排线数据，将排线数据入库
        /// YW_TaskInfo、YW_TaskOrderRelation、YW_TaskCarRelation
        /// </summary>
        /// <param name="Result"></param>
        /// <param name="Plandate"></param>
        private void SaveDataInfo(JObject Result,DateTime Plandate,string currentUserId)
        {
            //如何返回失败则记录日志
            //if (Result.Value<int>("status") != 200)
            //{
            //    log.Error(string.Format("解析数据时出错，数据返回状态错误。数据为{0}", Result.ToString()));
            //    //请求失败 记录日志
            //    return;
            //}            
           
            //JObject TaskList = Result[""];
            int i = 1;//自动编号 计数器
            foreach (JObject task in Result["body"]["tasklist"])
            {
                string taskid = "AT" + DateTime.Now.ToString("yyyyMMddhhmmssfff") + i.ToString();//任务编号 临时用GUID代替后继用自动编号 生成
                //DateTime planStartTime = DateTime.Now.AddDays(2);//先临时这样想再想这些逻辑是啥
                //获取订单总量
                var ordercount = 0;

                var losschickSQL = "select sum(OrderRoadLoss) OrderRoadLoss ,max(WaitDeliveryTime) WaitDeliveryTime from YW_OrderInfo where OrderCode in({0})";
                var ordercodes = "";
                foreach (JObject order in task["orderlist"])
                {
                    ordercodes += "'" + order.Value<string>("orderId") + "',";
                    ordercount += order.Value<int>("demandunitnum");
                }
                losschickSQL = string.Format(losschickSQL, ordercodes.Substring(0, ordercodes.Length - 1));
                DataTable dtlosschick = _helper.ExecuteDataSet(losschickSQL).Tables[0];
                //目前得不到路耗数量 。这是个坑回头，查一下订单表得到一下。
                var LossChickTotalCount = Convert.ToDouble(dtlosschick.Rows[0][0]);
                //planStartTime = Convert.ToDateTime(dtlosschick.Rows[0][1]);
                //生成任务主表SQL
                StringBuilder sbSql = new StringBuilder();
                sbSql.Append("Insert into YW_TaskInfo ( [TaskId],[PlanDeliveryDate],[DeliveryTaskStatus],[CreateUserId],[CreateTime],[OrderChickTotalCount],[OrderLossChickTotalCount]) values('" + taskid + "','" + Plandate.ToString("yyyy-MM-dd hh:mm:ss") + "','-1'," + currentUserId + ",getdate()," + ordercount + "," + LossChickTotalCount + ");\n");
                try
                {
                    _helper.ExecuteNonQuery(sbSql.ToString());
                }
                catch (Exception ex)
                {
                    log.Error(string.Format("数据入库时执行失败! 错误信息为：{1}\n 详细信息为:{2} \n SQL语句为：\n{0}\n", sbSql.ToString(), ex.Message, ex.StackTrace));
                }
                var j = 1;
                foreach (JObject carinfo in task["trucklist"])
                {
                    var carinfosql = string.Format("select * from BD_CarInfo where CarNumber='{0}'", carinfo.Value<string>("truckid"));
                    List<string> orders = JsonConvert.DeserializeObject<List<string>>(carinfo["orderrank"].ToString());
                    DataTable Dtcarinfo = _helper.ExecuteDataSet(carinfosql).Tables[0];
                    var k = 1;
                    foreach (JObject order in carinfo["pickupinfo"])
                    {
                        StringBuilder sbSql_TaskRelation = new StringBuilder();
                        //var taskorderid = DateTime.Now.ToString("yyyyMMddHHmmss") + i.ToString() + j.ToString() + k.ToString();
                        int autoIndex;
                        var taskorderid = Convert.ToInt64(CPAutoNumHelper.Instance().GetNextAutoNum("TaskOrderId", out autoIndex));
                        //生成任务与订单关系表SQL，（注：如果YW_TaskOrderRelation表中已经有此分厅的记录，则更新CarNumber字段）
                        sbSql_TaskRelation.AppendFormat("if not exists (select * from YW_TaskOrderRelation where TaskId='{1}' and OrderId='{2}' and GivetohallId='{3}' and BaseId='{4}' and HallId='{6}' and GoodsId='{10}' and '{12}' not in (select CarNumber from YW_TaskOrderRelation where TaskId='{1}' and OrderId='{2}' and GivetohallId='{3}' and BaseId='{4}' and HallId='{6}' and GoodsId='{10}')) " +
                            "Insert into YW_TaskOrderRelation (id,TaskId,OrderId,GivetohallId,BaseId,BaseName,HallId,HallName,VarietyId,VarietyName,GoodsId,GoodsName,CarNumber,Sort) values ({0},'{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}','{9}','{10}','{11}','{12}',{13}) " +
                            "else Update YW_TaskOrderRelation set CarNumber =(select CarNumber from YW_TaskOrderRelation where TaskId='{1}' and OrderId='{2}' and GivetohallId='{3}' and BaseId='{4}' and HallId='{6}' and GoodsId='{10}')+',{12}' where TaskId='{1}' and OrderId='{2}' and GivetohallId='{3}' and BaseId='{4}' and HallId='{6}' and GoodsId='{10}';\n", taskorderid, taskid, order.Value<string>("orderid"), order.Value<string>("givetohallid"), order.Value<string>("baseid"), order.Value<string>("basename"), order.Value<string>("hallid"), order.Value<string>("hallname"), order.Value<string>("varietyid"), order.Value<string>("varietyname"), order.Value<string>("goodsid"), order.Value<string>("goodsname"), Dtcarinfo.Rows[0]["CarNumber"].ToString(), orders.IndexOf(order.Value<string>("orderid")) + 1);

                        //生成任务订单与车辆关系表SQL（注：如果YW_TaskOrderRelation表中已经有此分厅的记录，则taskorderid用此条记录的taskorderid）
                        sbSql_TaskRelation.AppendFormat("if not exists (select * from YW_TaskOrderRelation where TaskId='{0}' and OrderId='{1}' and GivetohallId='{18}' and BaseId='{3}' and HallId='{5}' and GoodsId='{19}')  Insert into YW_TaskCarRelation ([TaskId],[OrderId],[TaskOrderId],[BaseId],[BaseName],[HallId],[HallName],[CarNumber],[SensorId],[GPSId],[MainDriverId],[MainDriverName],[MainDriverTel],[AssistantDriverId],[AssistantDriverName],[AssistantDriverTel],[OrderChickCountInCar],[HallLossCount])values('{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}','{9}','{10}','{11}','{12}','{13}','{14}','{15}',{16},{17}) else  Insert into YW_TaskCarRelation ([TaskId],[OrderId],[TaskOrderId],[BaseId],[BaseName],[HallId],[HallName],[CarNumber],[SensorId],[GPSId],[MainDriverId],[MainDriverName],[MainDriverTel],[AssistantDriverId],[AssistantDriverName],[AssistantDriverTel],[OrderChickCountInCar],[HallLossCount])values('{0}','{1}',(select id from YW_TaskOrderRelation where  TaskId='{0}' and OrderId='{1}' and GivetohallId='{18}' and BaseId='{3}' and HallId='{5}' and GoodsId='{19}'),'{3}','{4}','{5}','{6}','{7}','{8}','{9}','{10}','{11}','{12}','{13}','{14}','{15}',{16},{17});\n", taskid, order.Value<string>("orderid"), taskorderid, order.Value<string>("baseid"), order.Value<string>("basename"), order.Value<string>("hallid"), order.Value<string>("hallname"), Dtcarinfo.Rows[0]["CarNumber"].ToString(), Dtcarinfo.Rows[0]["SensorId"].ToString(), Dtcarinfo.Rows[0]["GPSId"].ToString(), Dtcarinfo.Rows[0]["MainDriverId"].ToString(), Dtcarinfo.Rows[0]["MainDriverName"].ToString(), Dtcarinfo.Rows[0]["MainDriverTel"].ToString(), Dtcarinfo.Rows[0]["AssistantDriverId"].ToString(), Dtcarinfo.Rows[0]["AssistantDriverName"].ToString(), Dtcarinfo.Rows[0]["AssistantDriverTel"].ToString(), order.Value<float>("buychickcount"), order.Value<float>("halllosscount"), order.Value<string>("givetohallid"), order.Value<string>("goodsid"));
                        try
                        {
                            _helper.ExecuteNonQuery(sbSql_TaskRelation.ToString());
                        }
                        catch (Exception ex)
                        {
                            log.Error(string.Format("数据入库时执行失败! 错误信息为：{1}\n 详细信息为:{2} \n SQL语句为：\n{0}\n", sbSql.ToString(), ex.Message, ex.StackTrace));
                        }                        
                        k++;
                    }
                    j++;
                }
                i++;
            }            
            //return false;
        }
    }
}